package part.g;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class EchoServer implements Runnable {

	private ExecutorService executor;
	private Lock lock;
	private int connectionNumber;
	private int messageNumber;

	public EchoServer() {
		executor = Executors.newSingleThreadExecutor();

		/*
		 * newCachedThreadPool can support numerous clients, I've tested it for
		 * 3, but I'm sure it could handle more. Messages all received by server
		 * when they're sent, not much waiting at all. *
		 */
		// executor = Executors.newCachedThreadPool();

		/*
		 * newFixedThreadPool(1), whomever connects first can send messages
		 * first. Others can also send messages, but these will not be echoed by
		 * the server until the client in front of them has quit.
		 */
		// executor = Executors.newFixedThreadPool(1);
		
		lock = new ReentrantLock();
		connectionNumber = 1;
		messageNumber = 1;
	}

	public void run() {
		try {
			ServerSocket socket = new ServerSocket(6969);

			System.out.println("Awaiting connections...");
			while (true) {
				Socket client = socket.accept();
				executor.execute(new ClientConnection(client,
						getConnectionNumber(), this));
				System.out.println("Connection accepted");
			}

		} catch (IOException ioe) {
			System.err.println(ioe);
		}
	}

	public int getMessageNumber() {
		lock.lock();
		try {
			return messageNumber++;
		} finally {
			lock.unlock();
		}
	}

	public int getConnectionNumber() {
		lock.lock();
		try {
			return connectionNumber++;
		} finally {
			lock.unlock();
		}
	}

	public static void main(String[] args) {
		new Thread(new EchoServer()).start();
	}
}
